package charpter14.lynx;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

class DynamicProxyHandler implements InvocationHandler {
	private Object proxied;

	private static Map<String, Integer> counterMap = new HashMap<String, Integer>();

	public DynamicProxyHandler(Object proxied) {
		this.proxied = proxied;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Integer counter = counterMap.get(method.getName());
		if (null == counter) {
			counter = 1;
		} else {
			counter++;
		}
		counterMap.put(method.getName(), counter);
		System.out.println("**** proxy: " + proxy.getClass() + ", method: "
				+ method + ", args: " + args + " " + counter + " times.");
		if (args != null)
			for (Object arg : args)
				System.out.println("  " + arg);
		return method.invoke(proxied, args);
	}
}

public class Twentytwo {
	public static void consumer(Interface iface) {
		iface.doSomething();
		iface.somethingElse("bonobo");
	}

	public static void main(String[] args) {
		RealObject real = new RealObject();
		consumer(real);
		// Insert a proxy and call again:
		Interface proxy = (Interface) Proxy.newProxyInstance(
				Interface.class.getClassLoader(),
				new Class[] { Interface.class }, new DynamicProxyHandler(real));
		consumer(proxy);
	}
}
